package partner

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

type CommonModel struct {
	handlers map[string]map[string][]gin.HandlerFunc
}

var _ Model = (*CommonModel)(nil)

func NewCommonModel() *CommonModel {
	return &CommonModel{
		handlers: make(map[string]map[string][]gin.HandlerFunc),
	}
}

func (m *CommonModel) GinHandlers() map[string]map[string][]gin.HandlerFunc {
	return m.handlers
}

func (m *CommonModel) RegisterGinHandler(method, path string, handlers ...gin.HandlerFunc) error {
	if method == "" || path == "" || len(handlers) == 0 {
		return fmt.Errorf("method / path / handlers must be specified")
	}
	if hs, _ := m.handlers[method]; hs == nil {
		m.handlers[method] = make(map[string][]gin.HandlerFunc)
	}
	if hs, _ := m.handlers[method][path]; hs == nil {
		m.handlers[method][path] = make([]gin.HandlerFunc, 0)
	}
	m.handlers[method][path] = append(m.handlers[method][path], handlers...)
	return nil
}

func (m *CommonModel) UnregisterGinHandler(method, path string) {
	if method == "" {
		return
	}
	if a, _ := m.handlers[method]; a == nil {
		return
	} else {
		if path == "" {
			delete(m.handlers, method)
			return
		}
		if b, _ := a[path]; b == nil {
			return
		} else {
			delete(a, path)
		}
	}
}

func (m *CommonModel) ClearGinHandler(method string) {
	delete(m.handlers, method)
}

func (m *CommonModel) UseGinMiddlewares(method, path string, handlers ...gin.HandlerFunc) error {
	l := len(handlers)
	if method == "" || path == "" || l == 0 {
		return fmt.Errorf("method / path / handlers must be specified")
	}
	if hs, _ := m.handlers[method]; hs == nil {
		m.handlers[method] = make(map[string][]gin.HandlerFunc)
	}
	if hs, _ := m.handlers[method][path]; hs == nil {
		m.handlers[method][path] = make([]gin.HandlerFunc, 0)
	}
	m.handlers[method][path] = append(m.handlers[method][path], handlers...)
	if l == len(m.handlers[method][path]) {
		return nil
	}
	copy(m.handlers[method][path][l:], m.handlers[method][path])
	for i := 0; i < l; i++ {
		m.handlers[method][path][i] = handlers[i]
	}
	return nil
}
